/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Training;

import DataBase.WekaDbReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import weka.classifiers.Classifier;
import weka.classifiers.meta.Vote;
import weka.classifiers.trees.J48;
import weka.core.Instances;
import weka.core.SelectedTag;
import weka.core.Utils;

/**
 *
 * @author fabio
 */
public class Training {

    /*
     * @TODO Class NumericToNominal() em atributos tipo spam
     */
    private String filePathModels;
    private Instances insts;

    public Training(String filePathModels) {
        this.filePathModels = filePathModels;
    }

    public void run() throws Exception {
        loadData();
        InstancesFilter filter = new InstancesFilter();
        insts = filter.filterInstances(insts);
        //System.out.println(insts.toString());

//        BufferedWriter writer = new BufferedWriter(new FileWriter("labeled.arff"));
//        writer.write(insts.toString());
//        writer.newLine();
//        writer.flush();
//        writer.close();


        //Start
        System.out.println("Start of model training");


        System.out.println("-Training J48 Model");
        Classifier cls;
        String[] tmpOptions;
        String classname;

//        //--J48
//        tmpOptions = Utils.splitOptions("weka.classifiers.trees.J48 -C 0.25 -M 2");
//        classname = tmpOptions[0];
//        tmpOptions[0] = "";
//        Classifier J48 = (Classifier) Utils.forName(Classifier.class, classname, tmpOptions);
        Classifier classJ48pru = classifierJ48pru();

        System.out.println("-Training Vote Model");
        Classifier[] classSet = new Classifier[1];
        classSet[0] = classJ48pru;
        //Vote classMultipleClassifier = classifierVode(classSet);
        Classifier classMultipleClassifier = classJ48pru;
        saveClassModel(classMultipleClassifier, "VoteClassifier.Model");

        //End
        //System.out.println(insts.toString());
        System.out.println("End of models training");
    }

    private void loadData() throws Exception {
        WekaDbReader dbReader = new WekaDbReader();
        Instances instances = dbReader.loadData("SELECT * FROM viewmails WHERE spam=1 OR spam=0");
        insts = instances;
    }

    private Classifier classifierJ48pru() throws Exception {
        Classifier classJ48 = new J48();
        //String[] options = new String[1];
        //options[0] = "-C 0.25 -M 2";
        //classJ48.setOptions(options);
        classJ48.buildClassifier(insts);
        return classJ48;
    }

    private Vote classifierVode(Classifier[] classifiers) throws Exception {
        Vote MultipleClassifier = new Vote();
        MultipleClassifier.setClassifiers(classifiers);
        MultipleClassifier.setCombinationRule(new SelectedTag(MultipleClassifier.MAJORITY_VOTING_RULE, MultipleClassifier.TAGS_RULES));
        MultipleClassifier.buildClassifier(insts);
        return MultipleClassifier;
    }

    private void saveClassModel(Classifier classi, String filename) throws IOException, Exception {
        weka.core.SerializationHelper.write(filePathModels + filename, classi);
    }
}
